package com.ellfors.common.base.adapter

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.viewbinding.ViewBinding
import com.chad.library.adapter4.BaseMultiItemAdapter

/**
 * 多布局适配器
 * 如果要使用GridLayoutManager请替换为QuickGridLayoutManager
 */
abstract class BaseMultiAdapter<T : Any> : BaseMultiItemAdapter<T>() {

    init {
        initDispatchItemType()
        initRegisterItemTypes()
    }

    private fun initDispatchItemType() {
        onItemViewType { position, list ->
            dispatchItemType(list[position], position)
        }
    }

    private fun initRegisterItemTypes() {
        registerItemTypes().forEach {
            createViewHolder(it)
        }
    }

    /**
     * 注册ItemType
     */
    abstract fun registerItemTypes(): List<Int>

    /**
     * 根据数据类型分发ItemType
     */
    abstract fun dispatchItemType(data: T, position: Int): Int

    /**
     * 创建ViewHolder
     */
    abstract fun createViewHolder(itemType: Int)

    /**
     * 注册ViewHolder 包含渲染部分
     *
     * @receiver Int    ItemType
     * @param createBinding             example: ItemMultiTestBinding::inflate    构建ViewBinding
     * @param convert                   渲染ViewHolder
     * @param isFullSpanItem            是否充满一行
     * @param onCreate                  创建ViewHolder
     * @param onViewAttachedToWindow    显示到Window事件
     * @param onViewDetachedFromWindow  不显示到Window事件
     * @param onViewRecycled            被回收事件
     */
    protected fun <VB : ViewBinding> Int.registerItem(
        createBinding: (inflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> VB,
        convert: (holder: MultiViewHolder<VB>, position: Int, item: T?) -> Unit,
        isFullSpanItem: Boolean = false,
        onCreate: (context: Context, parent: ViewGroup) -> MultiViewHolder<VB> = { context, parent ->
            MultiViewHolder(
                createBinding(
                    LayoutInflater.from(context), parent, false
                )
            )
        },
        onViewAttachedToWindow: (holder: ViewHolder) -> Unit = {},
        onViewDetachedFromWindow: (holder: ViewHolder) -> Unit = {},
        onViewRecycled: (holder: ViewHolder) -> Unit = {}
    ) {
        addItemType(this, object : OnMultiItemAdapterListener<T, MultiViewHolder<VB>> {
            override fun onBind(holder: MultiViewHolder<VB>, position: Int, item: T?) {
                convert(holder, position, item)
            }

            override fun onCreate(
                context: Context, parent: ViewGroup, viewType: Int
            ): MultiViewHolder<VB> {
                return onCreate(context, parent)
            }

            override fun isFullSpanItem(itemType: Int): Boolean {
                return isFullSpanItem
            }

            override fun onViewAttachedToWindow(holder: ViewHolder) {
                onViewAttachedToWindow(holder)
            }

            override fun onViewDetachedFromWindow(holder: ViewHolder) {
                onViewDetachedFromWindow(holder)
            }

            override fun onViewRecycled(holder: ViewHolder) {
                onViewRecycled(holder)
            }
        })
    }

    protected class MultiViewHolder<VB : ViewBinding>(val binding: VB) : ViewHolder(binding.root)
}